﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using Microsoft.Win32;
using System.Windows.Forms;
using hopchat;


namespace ChemistryApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.pictureBoxLoading.Image = System.Drawing.Image.FromFile(@"ajax-loader.gif");
            imgLoading.Visibility = System.Windows.Visibility.Hidden;
            
        }

      

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        public List<hop_chat> lstINPUT = new List<hop_chat>();
        public List<hop_chat> lstOUTPUT = new List<hop_chat>();
    
        private void btnInput_MouseDown(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog input = new System.Windows.Forms.OpenFileDialog();
            input.DefaultExt = ".xml";
            input.Filter = "XML Input File (.xml)|*.xml";
            if (input.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                restoreDefault();
                string path = input.FileName;
                //System.Windows.MessageBox.Show(fileInput.ToString());

                XmlDocument de = new XmlDocument();
                de.Load(path);

                XmlNode Node = de.GetElementsByTagName("INPUT")[0];

                foreach (XmlNode x in Node.ChildNodes)
                {
                    if (x.Name.ToLower() == "hopchat")
                    {
                        XmlDocument hc = new XmlDocument();
                        XmlElement hcc = hc.CreateElement("hopchat");
                        hcc.InnerXml = x.InnerXml;
                        hc.AppendChild(hcc);

                        hop_chat hccc = new hop_chat(hc);
                        lstINPUT.Add(hccc);
                    }
                }

                Node = de.GetElementsByTagName("OUTPUT")[0];

                foreach (XmlNode x in Node.ChildNodes)
                {
                    if (x.Name.ToLower() == "hopchat")
                    {
                        XmlDocument hc = new XmlDocument();
                        XmlElement hcc = hc.CreateElement("hopchat");
                        hcc.InnerXml = x.InnerXml;
                        hc.AppendChild(hcc);

                        hop_chat hccc = new hop_chat(hc);
                        lstOUTPUT.Add(hccc);
                    }
                }
                
                foreach (hop_chat x in lstINPUT)
                    addDATA(x.ToString(),txtInput);
                    //txtInput.Selection.Text += x.ToString() + "\r\n";

                foreach (hop_chat x in lstOUTPUT)
                    addDATA(x.ToString(),txtOutput);
                    //txtOutput.Selection.Text += x.ToString() + "\r\n";

                //System.Windows.MessageBox.Show("done");
            }

        }

        private void restoreDefault()
        {
            txtInput.Document.Blocks.Clear();
            txtOutput.Document.Blocks.Clear();
            txtInfo.Document.Blocks.Clear();
            lstINPUT.Clear();
            lstOUTPUT.Clear();
        }

        delegate void addData(string hc, System.Windows.Controls.RichTextBox RTC);
        private void addDATA(string hc,System.Windows.Controls.RichTextBox RTC)
        {
            
            RTC.Selection.Select(RTC.Document.ContentEnd, RTC.Document.ContentEnd);
            string temp= "";
            for (int i = 0; i < hc.Length; i++)
            {
                char x = hc[i];
                if ('0' < x && x < '9')
                {
                    RTC.Selection.Text += temp; temp = "";
                    RTC.Selection.Select(RTC.Document.ContentEnd, RTC.Document.ContentEnd);
                    RTC.Selection.Text += x.ToString();

                    RTC.Selection.ApplyPropertyValue(Inline.FontSizeProperty, 10.0);
                    RTC.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Subscript);

                    RTC.Selection.Select(RTC.Selection.End, RTC.Selection.End);
                    RTC.Selection.Text += hc[++i];                    
                    //RTC.Selection.Select(RTC.Document.ContentEnd, RTC.Document.ContentEnd);

                    RTC.Selection.ApplyPropertyValue(Inline.FontSizeProperty, 14.0);
                    RTC.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Baseline);
  
                    RTC.Selection.Select(RTC.Selection.End, RTC.Selection.End);
                    //RTC.Selection.Text = "";
                }
                else
                {
                    temp += x;
                }
            }
            RTC.Selection.Text += temp + "\n";
        }

        private void btnInfo_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if(imgHD.Visibility == System.Windows.Visibility.Hidden)
                imgHD.Visibility = System.Windows.Visibility.Visible;
            else
                imgHD.Visibility = System.Windows.Visibility.Hidden;
        }




        private bool KiemTraLoiGiai(List<ruleReport> solution, List<hop_chat> inp, List<hop_chat> outp)
        {
            for (int i = 0; i < solution.Count -1; i++)
            {
                if (solution[i].chatThamGia == null)
                    solution[i].rule.Xuly(inp);
                else
                {
                    if (TapLuat.checkTapCon(inp, solution[i].chatThamGia))
                    {
                        inp.Add(solution[i].sanpham[0]);
                        if (solution[i].sanpham.Count > 1)
                        {
                            inp.Add(solution[i].sanpham[1]);
                        }

                    }
                    else
                        return false;
                }
            }


            bool result =  TapLuat.checkTapCon(inp, outp);
            return result;
        }



        private List<ruleReport> LoiGiaiTot(List<ruleReport> solution, List<hop_chat> inp, List<hop_chat> outp)
        {
            for (int i = solution.Count - 2 ; i > -1; i--)
            {
                List<hop_chat> input = cloneInput(inp);
                List<hop_chat> output = cloneInput(outp);
                
                List<ruleReport> D = new List<ruleReport>(solution);
                D.RemoveAt(i);
                bool temp = KiemTraLoiGiai(D,input,output);

                if (temp )
                    solution = D;
            }
            return solution;
        }

        private List<hop_chat> cloneInput(List<hop_chat> a)
        {

            List<hop_chat> result = new List<hop_chat>();
            foreach (hop_chat hc in a)
                result.Add(new hop_chat(hc));

            return result;
        }

        private void btnStart_MouseDown(object sender, MouseButtonEventArgs e)
        {

            

            imgHD.Visibility = System.Windows.Visibility.Hidden;

            txtInfo.Document.Blocks.Clear();

            imgLoading.Visibility = System.Windows.Visibility.Visible;
            System.Threading.Thread temp = new System.Threading.Thread(new System.Threading.ThreadStart(thread));
            temp.Start();
            

            
        }
        delegate void load();

        private void thread(){
            
            List<hop_chat> input = cloneInput(lstINPUT);
            List<hop_chat> output = cloneInput(lstOUTPUT);

             //Require the luat.xml file to be in same folder with the executable file 
            TapLuat ruleSet = new TapLuat(@"luat.xml");

            List<ruleReport> kq = ruleSet.Solve(input, output);

            kq = LoiGiaiTot(kq, lstINPUT, lstOUTPUT);

            foreach (ruleReport rp in kq)
            {
                Object[] a = {rp.report,txtInfo};
                this.Dispatcher.Invoke(new addData(addDATA),a);
            }

            Object[] b = { "Chung ta ton " + (kq.Count - 1).ToString() + " buoc ", txtInfo };
            this.Dispatcher.Invoke(new addData(addDATA), b);


            this.Dispatcher.Invoke(
                (System.Windows.Forms.MethodInvoker)delegate() { imgLoading.Visibility = System.Windows.Visibility.Hidden; });
            
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            restoreDefault();
        }
    }
}
